#pragma once

#include "..\\headers.default.h"
#include "..\\headers.cv.h"

#include "ipfe_base.h"
#include "ipfe_shape_pattern.h"

using namespace loirey;

class C_IPFC_ResponseUser_Mean_and_Variance : public C_IPFC_ResponseUser
{
public:
	static const int MODE_MEAN_IN_CELL = 1;
	static const int MODE_MEAN_OVER_BLOCK = 2;
	static const int MODE_VARIANCE_IN_CELL = 4;
	static const int MODE_VARIANCE_OVER_BLOCK = 8;
public:
	const CShapePatternList* pFixedShapePatternList;
public:
	int Mode, StatisticAmount;
	int FeatureDimension;
	CIntegralResponse mapX1;
	CIntegralResponse mapX2;

public:
	C_IPFC_ResponseUser_Mean_and_Variance();
	C_IPFC_ResponseUser_Mean_and_Variance(int Mode, const CShapePatternList* pFixedShapePatternList);
	virtual ~C_IPFC_ResponseUser_Mean_and_Variance();
	virtual void SetMode(int Mode);
	virtual void SetShapePatternList(const CShapePatternList* pFixedShapePatternList);
public:
	virtual C_IPFC_ResponseUser* myClone() const;
	virtual size_t GetMemoryUsage() const;
	virtual int GetInputResonseDimension() const;
	virtual int GetFeatureDimension() const;
	virtual int RecomputeFeatureDimension();
	virtual void ClearContent();
	virtual void SetInputResponse(const double* pSrcResponse, int W, int H);
	virtual void ComputeFeature(int x, int y, int FeatureIndex, double* DstData, bool* DstGotFlag);
};

class C_IPFC_ResponseUser_MeanAndVairance : public C_IPFC_ResponseUser
{
public:
	const CShapePatternList* pFixedShapePatternList;
public:
	int FeatureDimension;
	CIntegralMeanAndVariance IntegralMeanAndVariance;

public:
	C_IPFC_ResponseUser_MeanAndVairance();
	C_IPFC_ResponseUser_MeanAndVairance(const CShapePatternList* pFixedShapePatternList);
	virtual ~C_IPFC_ResponseUser_MeanAndVairance();
	virtual void SetShapePatternList(const CShapePatternList* pFixedShapePatternList);
public:
	virtual C_IPFC_ResponseUser* myClone() const;
	virtual size_t GetMemoryUsage() const;
	virtual int GetInputResonseDimension() const;
	virtual int GetFeatureDimension() const;
	virtual int RecomputeFeatureDimension();
	virtual void ClearContent();
	virtual void SetInputResponse(const double* pSrcResponse, int W, int H);
	virtual void ComputeFeature(int x, int y, int FeatureIndex, double* DstData, bool* DstGotFlag);
};

class C_IPFC_ResponseUser_BlockNormalizer : public C_IPFC_ResponseUser
{
public:
	const CShapePatternList* pFixedShapePatternList;
	bool fAverageInCell;
	CMyNormalizer* pNormalizer;
	bool fSharedNormalizer;
public:
	int InputDimension, FeatureDimension, BlockAmount;
	CSimpleTypeArray<CIntegralResponse> IntegralResponseList;
	CSimpleTypeArray<int> BlockFeatureStartList;

public:
	C_IPFC_ResponseUser_BlockNormalizer();
	C_IPFC_ResponseUser_BlockNormalizer(
		int InputResponseDimension, const CShapePatternList* pFixedShapePatternList,
		bool fAverageInCell,
		CMyNormalizer* pNormalizer, bool fSharedNormalizer);
	virtual ~C_IPFC_ResponseUser_BlockNormalizer();
	virtual void SetInputResponseDimension(int InputResponseDimension);
	virtual void SetShapePatternList(const CShapePatternList* pFixedShapePatternList);
	virtual void SetIfAverageInCell(bool fAverageInCell);
	virtual void SetNormalizer(CMyNormalizer* pNormalizer, bool fSharedNormalizer);
public:
	virtual C_IPFC_ResponseUser* myClone() const;
	virtual size_t GetMemoryUsage() const;
	virtual int GetInputResonseDimension() const;
	virtual int GetFeatureDimension() const;
	virtual int RecomputeFeatureDimension();
	virtual void ClearContent();
	virtual void SetInputResponse(const double* pSrcResponse, int W, int H);
	virtual void ComputeFeature(int x, int y, int FeatureIndex, double* DstData, bool* DstGotFlag);
};

class C_IPFC_ResponseUser_2D_RectHistogram : public C_IPFC_ResponseUser
{
public:
	class CDescriptorConfig
	{
	public:
		static const int L2_NORM = 0;
		static const int L2_HYS = 1;
	public:
		int BinAmount;
		double wCelPix, hCelPix;
		int wWinCel, hWinCel;
		int wBlkCel, hBlkCel;
		double WeightScale;
		int normalizer;
		double e, hysth;

		int aWinCel;
		int aBlkCel;
		int wWinBlk, hWinBlk;
		int aWinBlk;
		int lenBlkDescriptor;
		int lenWinDescriptor;

		double base_blk_pix_x;
		double base_blk_pix_y;

	public:
		CDescriptorConfig();
		void SetDefaultParameters();
		void myInit(istream& inStream);
		void myInit(
			int BinAmount,
			double wCelPix, double hCelPix,
			int wWinCel, int hWinCel,
			int wBlkCel, int hBlkCel,
			double WeightScale,
			string strNormalizer,
			double e, double hysTheshold
			);
	};
	
public:
	class CResponseConfig
	{
	public:
		bool fAreBinsWrapped;
		bool fDoGlobalResponseNormalization;
		int ResponseIndex_for_Weight;
		int ResponseIndex_for_Value;
		double ValueBoundA, ValueBoundB;

	public:
		CResponseConfig();
	};

public:
	int W, H, WH;
protected:
	CDescriptorConfig _DescriptorConfig;
	CResponseConfig _ResponseConfig;
	int _Dim;
	int _lenBlkDescriptor;
private:
	double __ONE;
	const double* __QW_HEAD;
	const double* __QV_HEAD;
	int __QW_STEP;
	int __QV_STEP;
	CHistogramConfig __HistogramConfig;
	bool __fPreprocessed;
protected:
	int _dx, _dy;
	CSimpleTypeArray<double> _gau_weight_x;
	CSimpleTypeArray<double> _gau_weight_y;
	CSimpleTypeArray<int> _cell_base_x;
	CSimpleTypeArray<int> _cell_base_y;
	CSimpleTypeArray<double> _lin_weight_x;
	CSimpleTypeArray<double> _lin_weight_y;
	double* _q_gw_x;
	double* _q_gw_y;
	int* _q_cb_x;
	int* _q_cb_y;
	double* _q_lw_x;
	double* _q_lw_y;
public:
	CSimpleTypeArray<double> matW_A;
	CSimpleTypeArray<double> matW_B;
	CSimpleTypeArray<int> matV_A;
	CSimpleTypeArray<int> matV_B;
	CSimpleTypeArray<int> BlkCache;
	CSimpleTypeArray<double> BlkData;

public:
	C_IPFC_ResponseUser_2D_RectHistogram();
	C_IPFC_ResponseUser_2D_RectHistogram(
		const CDescriptorConfig& DescriptorConfig,
		const CResponseConfig& ResponseConfig
		);
	virtual ~C_IPFC_ResponseUser_2D_RectHistogram();
	virtual void InitHistogramConfig(
		const CDescriptorConfig& DescriptorConfig,
		const CResponseConfig& ResponseConfig
		);
	virtual void Preprocess_and_ClearComputingHistogry();
public:
	virtual void SetResponseImage_A(const double* SrcResponse);
	virtual void Preprocess_A();
	virtual void ComputeBlock_A(double* DstData, int center_x, int center_y);
public:
	virtual C_IPFC_ResponseUser* myClone() const;
	virtual size_t GetMemoryUsage() const;
	virtual int GetInputResonseDimension() const;
	virtual int GetFeatureDimension() const;
	virtual int RecomputeFeatureDimension();
	virtual void ClearContent();
	virtual void SetInputResponse(const double* pSrcResponse, int W, int H);
	virtual void ComputeFeature(int x, int y, int FeatureIndex, double* DstData, bool* DstGotFlag);
};

//////// NOTICE!! The GetMemoryUsage() function of CRectHistogram_of_2D_Response_IPFC is not built yet!!
//////TODO
////
////class CRectHistogram_of_2D_Response_IPFC : public CFilterResponseIPFC
////{
////public:
////	class CDescriptorConfig
////	{
////	public:
////		static const int L2_NORM = 0;
////		static const int L2_HYS = 1;
////	public:
////		int BinAmount;
////		double wCelPix, hCelPix;
////		int wWinCel, hWinCel;
////		int wBlkCel, hBlkCel;
////		double WeightScale;
////		int normalizer;
////		double e, hysth;
////
////		int aWinCel;
////		int aBlkCel;
////		int wWinBlk, hWinBlk;
////		int aWinBlk;
////		int lenBlkDescriptor;
////		int lenWinDescriptor;
////
////		double base_blk_pix_x;
////		double base_blk_pix_y;
////
////	public:
////		CDescriptorConfig();
////		void Clear();
////		void myInit(istream& inStream);
////		void myInit(
////			int BinAmount,
////			double wCelPix, double hCelPix,
////			int wWinCel, int hWinCel,
////			int wBlkCel, int hBlkCel,
////			double WeightScale,
////			string strNormalizer,
////			double e, double hysTheshold
////			);
////	};
////public:
////	class CResponseConfig
////	{
////	public:
////		bool fAreBinsWrapped;
////		bool fDoGlobalResponseNormalization;
////		int ResponseIndex_for_Weight;
////		int ResponseIndex_for_Value;
////		double ValueBoundA, ValueBoundB;
////	};
////
////protected:
////	const CDescriptorConfig* _pDescriptorConfig;
////	const CResponseConfig* _pResponseConfig;
////	int _Dim;
////	int _lenBlkDescriptor;
////private:
////	double __ONE;
////	const double* __QW_HEAD;
////	const double* __QV_HEAD;
////	int __QW_STEP;
////	int __QV_STEP;
////	CHistogramConfig __HistogramConfig;
////	bool __fPreprocessed;
////protected:
////	// Mode A
////	int _dx, _dy;
////	CSimpleTypeArray<double> _gau_weight_x;
////	CSimpleTypeArray<double> _gau_weight_y;
////	CSimpleTypeArray<int> _cell_base_x;
////	CSimpleTypeArray<int> _cell_base_y;
////	CSimpleTypeArray<double> _lin_weight_x;
////	CSimpleTypeArray<double> _lin_weight_y;
////	double* _q_gw_x;
////	double* _q_gw_y;
////	int* _q_cb_x;
////	int* _q_cb_y;
////	double* _q_lw_x;
////	double* _q_lw_y;
////protected:
////
////public:
////	CSimpleTypeArray<double> matW_A;
////	CSimpleTypeArray<double> matW_B;
////	CSimpleTypeArray<int> matV_A;
////	CSimpleTypeArray<int> matV_B;
////
////	CSimpleTypeArray<int> BlkCache;
////	CSimpleTypeArray<double> BlkData;
////
////public:
////	CRectHistogram_of_2D_Response_IPFC();
////	CRectHistogram_of_2D_Response_IPFC(
////		CImageFilterBank* pFixedImageFilterBank,
////		int ImageExtent,
////		const CSimpleTypeArray<int> InputResponseList,
////		const CResponseConfig* pFixedResponseConfig,
////		const CDescriptorConfig* pFixDescriptorConfig
////		);
////	virtual ~CRectHistogram_of_2D_Response_IPFC();
////	void InitHistogramConfig(
////		const CResponseConfig* pFixedResponseConfig,
////		const CDescriptorConfig* pFixDescriptorConfig
////		);
////	void Preprocess_and_ClearComputingHistogry();
////protected:
////	// Mode A
////	void SetResponseImage_A(const double* SrcResponse);
////	void Preprocess_A();
////	void ComputeBlock_A(double* DstData, int center_x, int center_y);
////public:
////	virtual CImagePositionFeatureCalculator* myClone() const;
////	virtual void SetResponseImage(const double* SrcResponse);
////	virtual int GetFeatureDimension();
////	virtual void CalcFeature(
////		int x, int y, int FeatureIndex,
////		double* DstData, bool* DstGotFlag
////		);
////};

////////class CResponseMeanIPFC : public CFilterResponseIPFC
////////{
////////protected:
////////	const CShapePatternList* _pShapePatternList;
////////	int _PatternAmount;
////////public:
////////	CSimpleTypeArray<CIntegralResponse> IntegralResponseList;
////////
////////public:
////////	CResponseMeanIPFC();
////////	CResponseMeanIPFC(
////////		CImageFilterBank* pFixedImageFilterBank,
////////		int ImageExtent,
////////		const CSimpleTypeArray<int>& InputResponseList,
////////		const CShapePatternList* pFixedShapePatternList
////////		);
////////	virtual ~CResponseMeanIPFC();
////////	void InitPatternList(const CShapePatternList* pFixedShapePatternList);
////////public:
////////	virtual CImagePositionFeatureCalculator* myClone() const;
////////	virtual void SetResponseImage(const double* SrcResponse);
////////	virtual int GetFeatureDimension();
////////	virtual void CalcFeature(
////////		int x, int y, int FeatureIndex,
////////		double* DstData, bool* DstGotFlag
////////		);
////////	virtual size_t GetMemoryUsage() const;
////////};
////////
////////class CResponseMeanAndVarianceIPFC : public CFilterResponseIPFC
////////{
////////protected:
////////	const CShapePatternList* _pShapePatternList;
////////	int _PatternAmount;
////////public:
////////	CSimpleTypeArray<CIntegralMeanAndVariance> IntegralMeanAndVarianceList;
////////
////////public:
////////	CResponseMeanAndVarianceIPFC();
////////	CResponseMeanAndVarianceIPFC(
////////		CImageFilterBank* pFixedImageFilterBank,
////////		int ImageExtent,
////////		const CSimpleTypeArray<int>& InputResponseList,
////////		const CShapePatternList* pFixedShapePatternList
////////		);
////////	virtual ~CResponseMeanAndVarianceIPFC();
////////	void InitPatternList(const CShapePatternList* pFixedShapePatternList);
////////public:
////////	virtual CImagePositionFeatureCalculator* myClone() const;
////////	virtual void SetResponseImage(const double* SrcResponse);
////////	virtual int GetFeatureDimension();
////////	virtual void CalcFeature(
////////		int x, int y, int FeatureIndex,
////////		double* DstData, bool* DstGotFlag
////////		);
////////	virtual size_t GetMemoryUsage() const;
////////};

